import java.io.*;

import javax.swing.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;

/*
 * TODO:
 * 1. 100个词以后就不再增加新词 done
 * 2. 每个单词可以有备注 done
 * 3. 用户可以设置新单词出现的概率 done
 * 4. 加入快捷键 done
 */

class MultilineLabel extends JEditorPane {
	public void updateUI() {
		super.updateUI();
		setHighlighter(null);
		setEditable(false);
		LookAndFeel.installBorder(this, "Label.border");
		LookAndFeel.installColorsAndFont(this, "Label.background",
				"Label.foreground", "Label.font");
	}
}

class Window extends JFrame {
	private static final long serialVersionUID = 1L;

	private JLabel lbl_word = new JLabel("");

	private JLabel lbl_pron = new JLabel("");

	private MultilineLabel lbl_def_cn = new MultilineLabel();

	private JTextArea txt_note = new JTextArea();

	private JLabel lbl_status = new JLabel("");

	private JButton btn_remember = new JButton("Remember");

	private JButton btn_forget = new JButton("Forget");

	private JButton btn_easy = new JButton("Easy");

	private User user;

	private int word_id;

	private int get_cnt_viewed() {
		int cnt_viewed = 0;
		for (int i = 0; i < user.now_dict.cnt_words; ++i) {
			if (user.hit[i] + user.miss[i] != 0) {
				++cnt_viewed;
			}
		}
		return cnt_viewed;
	}

	private int get_cnt_learning() {
		int cnt_learning = 0;
		for (int i = 0; i < user.now_dict.cnt_words; ++i) {
			if (user.hit[i] + user.miss[i] != 0) {
				if (user.easy[i] == 0)
					++cnt_learning;
			}
		}
		return cnt_learning;
	}

	private void refresh() {
		lbl_word.setText(user.now_dict.word[word_id]);
		lbl_pron.setText(user.now_dict.pron[word_id]);
		lbl_def_cn.setText("<body><center>" + user.now_dict.def_cn[word_id]
				+ "</center></body>");
		txt_note.setText(user.note[word_id]);

		int cnt_viewed = get_cnt_viewed();
		int cnt_learning = get_cnt_learning();

		lbl_status.setText("Hit:" + user.hit[word_id] + "   Miss:"
				+ user.miss[word_id] + "   " + cnt_learning + "/" + cnt_viewed
				+ "/" + user.now_dict.cnt_words);
	}

	private void hide_def() {
		lbl_def_cn.setText("");
		txt_note.setVisible(false);
	}

	private void show_def() {
		lbl_def_cn.setText("<body><center><font size=6>"
				+ user.now_dict.def_cn[word_id] + "</font></center></body>");
		txt_note.setVisible(true);
	}

	private void go_next() {
		user.save_note(word_id, txt_note.getText());

		if (get_cnt_learning() < user.max_learn)
			word_id = user.get_next(30);
		else
			word_id = user.get_next(0);
		refresh();
		hide_def();
	}

	private void btn_remember_on_click() {
		if (btn_remember.getText() == "Remember") {
			btn_remember.setEnabled(true);
			btn_remember.setText("Correct");
			btn_forget.setText("Wrong");
			show_def();
		} else if (btn_remember.getText() == "Correct") {
			btn_remember.setEnabled(true);
			btn_remember.setText("Remember");
			btn_forget.setText("Forget");
			user.correct(word_id);
			go_next();
		}
	}

	private void btn_forget_on_click() {
		if (btn_forget.getText() == "Forget") {
			btn_remember.setEnabled(false);
			btn_forget.setText("Next");
			user.forget(word_id);
			refresh();
			show_def();
		} else if (btn_forget.getText() == "Wrong") {
			btn_remember.setEnabled(true);
			btn_remember.setText("Remember");
			btn_forget.setText("Forget");
			user.wrong(word_id);
			go_next();
		} else if (btn_forget.getText() == "Next") {
			btn_remember.setEnabled(true);
			btn_remember.setText("Remember");
			btn_forget.setText("Forget");
			go_next();
		}
	}

	private void btn_easy_on_click() {
		btn_remember.setEnabled(true);
		btn_remember.setText("Remember");
		btn_forget.setText("Forget");
		user.easy(word_id);
		go_next();
	}

	public Window() {
		try {
			user = new User();
			String user_name = "tmp";

			File f = new File("config.xml");
			if (!f.exists()) {
				FileWriter fw = new FileWriter(f);
				PrintWriter out = new PrintWriter(fw);
				out.printf("<user user_name=\"Ader\">\n");
				out.printf("</user>\n");
				fw.close();
				out.close();
			}

			try {
				DocumentBuilderFactory factory = DocumentBuilderFactory
						.newInstance();
				DocumentBuilder builder = factory.newDocumentBuilder();
				Document doc = builder.parse(f);
				user_name = doc.getElementsByTagName("user").item(0)
						.getAttributes().getNamedItem("user_name")
						.getTextContent();
			} catch (Exception e) {
				e.printStackTrace();
			}

			try {
				user.get_record(user_name);
			} catch (Exception e) {
				try {
					user.new_record(user_name);
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}

		} catch (Exception e1) {
			e1.printStackTrace();
		}

		Font fnt_lbl_word = new Font("Lucida Grande", Font.PLAIN, 64);
		Font fnt_lbl_pron = new Font("Lucida Grande", Font.PLAIN, 32);
		Font fnt_lbl_status = new Font("Lucida Grande", Font.PLAIN, 24);
		Font fnt_btn = new Font("SimSun", Font.PLAIN, 24);

		lbl_word.setFont(fnt_lbl_word);
		lbl_pron.setFont(fnt_lbl_pron);
		lbl_def_cn.setContentType("text/html");
		lbl_status.setFont(fnt_lbl_status);
		txt_note.setFont(fnt_lbl_status);
		btn_remember.setFont(fnt_btn);
		btn_forget.setFont(fnt_btn);
		btn_easy.setFont(fnt_btn);

		lbl_word.setAlignmentX(Component.CENTER_ALIGNMENT);
		lbl_pron.setAlignmentX(Component.CENTER_ALIGNMENT);
		lbl_def_cn.setAlignmentX(Component.CENTER_ALIGNMENT);
		txt_note.setAlignmentX(Component.CENTER_ALIGNMENT);
		lbl_status.setAlignmentX(Component.CENTER_ALIGNMENT);

		txt_note.setPreferredSize(new Dimension(500, 100));
		txt_note.setMaximumSize(new Dimension(500, 200));
		txt_note.setMinimumSize(new Dimension(500, 100));

		lbl_def_cn.setPreferredSize(new Dimension(500, 100));
		lbl_def_cn.setMaximumSize(new Dimension(500, 200));
		lbl_def_cn.setMinimumSize(new Dimension(500, 100));

		btn_remember.setPreferredSize(new Dimension(150, 40));
		btn_remember.setMaximumSize(new Dimension(150, 40));
		btn_remember.setMinimumSize(new Dimension(150, 40));
		btn_forget.setPreferredSize(new Dimension(150, 40));
		btn_forget.setMaximumSize(new Dimension(150, 40));
		btn_forget.setMaximumSize(new Dimension(150, 40));
		btn_easy.setPreferredSize(new Dimension(150, 40));
		btn_easy.setMaximumSize(new Dimension(150, 40));
		btn_easy.setMaximumSize(new Dimension(150, 40));

		setTitle("Ader Words");

		setSize(800, 600);

		Box fr = Box.createVerticalBox();

		fr.add(Box.createRigidArea(new Dimension(50, 20)));
		fr.add(lbl_word);
		fr.add(Box.createRigidArea(new Dimension(50, 20)));
		fr.add(lbl_pron);
		fr.add(Box.createRigidArea(new Dimension(50, 20)));
		fr.add(lbl_def_cn);
		fr.add(Box.createRigidArea(new Dimension(50, 20)));
		fr.add(txt_note);
		fr.add(Box.createVerticalGlue());
		fr.add(lbl_status);
		fr.add(Box.createRigidArea(new Dimension(50, 20)));

		Box btns = Box.createHorizontalBox();
		btns.setAlignmentX(Component.CENTER_ALIGNMENT);
		btns.add(btn_remember);
		btns.add(Box.createRigidArea(new Dimension(20, 20)));
		btns.add(btn_forget);
		btns.add(Box.createRigidArea(new Dimension(20, 20)));
		btns.add(btn_easy);
		fr.add(btns);
		fr.add(Box.createRigidArea(new Dimension(20, 20)));

		add(fr);

		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				try {
					user.save_record();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
				System.exit(0);
			}

			public void windowOpened(WindowEvent e) {
				try {
					user.get_record("Ader");
					go_next();
				} catch (Exception e1) {
					try {
						user.new_record("Ader");
						user.save_record();
					} catch (Exception e2) {
						e2.printStackTrace();
					}
					try {
						user.get_record("Ader");
					} catch (Exception e2) {
						e2.printStackTrace();
					}
					go_next();
				}
			}
		});

		this.setFocusable(true);
		
		lbl_word.setFocusable(false);
		lbl_pron.setFocusable(false);
		lbl_def_cn.setFocusable(false);
		lbl_status.setFocusable(false);
		btn_remember.setFocusable(false);
		btn_forget.setFocusable(false);
		btn_easy.setFocusable(false);

		addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				if (e.getKeyChar() == 'n') {
					btn_remember_on_click();
				} else if (e.getKeyChar() == 'm') {
					btn_forget_on_click();
				} else if (e.getKeyChar() == ',') {
					btn_easy_on_click();
				}
			}
		});

		btn_remember.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_remember_on_click();
			}
		});

		btn_forget.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_forget_on_click();
			}
		});

		btn_easy.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_easy_on_click();
			}
		});
		
		txt_note.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				if ((e.getKeyCode() & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK
						&& KeyEvent.getKeyText(e.getKeyCode()) == "Enter") {
					requestFocus();
				}
			}
		});
	}
}

public class Main {
	static Window w = new Window();

	public static void main(String args[]) {
		w.setLocationRelativeTo(null);
		w.setVisible(true);
	}
}
